<template>
  <div class="login">
    <Particles
        id="tsparticles"
        class="login__particles"
        :options="options"
    />
    <div class="loginPart">
      <h2>用户登录</h2>
      <el-form
          ref="ruleFormRef"
          :model="user"
          status-icon
          :rules="rules"
          label-width="100px"
          class="demo-ruleForm"
          style="transform:translate(-30px);"
          @submit.prevent
      >
        <el-form-item label="账号：" prop="account">
          <el-input v-model="user.account" placeholder="请输入账号" maxlength="20" clearable/>
        </el-form-item>
        <el-form-item label="密码：" prop="password">
          <el-input v-model="user.password" type="password" placeholder="请输入密码" maxlength="20" show-password
                    clearable/>
        </el-form-item>
        <el-form-item label="验证码：" prop="verifyCode">
          <el-input
              style="width: 150px;"
              v-model="user.verifyCode"
              placeholder="请输入验证码"
              maxlength="4"
              clearable
              @keyup.enter="onSubmit(ruleFormRef)"
          />
          <canvas ref="captchaCanvas" @click="resetCode" style="width: 250px;height: 120px"></canvas>
        </el-form-item>
        <el-button color="#44465f" class="btn" type="primary" @click="onSubmit(ruleFormRef)">登录</el-button>
<!--        <VerificationGame v-if="state.showVerificationGame" @game-completed="handleGameCompleted" />-->
<!--        <button v-else @click="startVerificationGame">开始验证</button>-->
        <div style="text-align: right;transform:translate(0,30px);">
          <el-link type="warning" @click="changeRegist">没有账号？去注册</el-link>
        </div>
      </el-form>
    </div>
  </div>
  <verification-game v-if="showVerificationGame" />
</template>

<script setup lang="ts">
import { reactive, ref, onMounted } from 'vue'
import router from '@/router/index'
import { getPri, login } from '@/api/Login'
import { tokenStore, accountStore, loginStore, priStore } from '@/store/modules/user'
import { loginReq } from '@/api/types/loginReq'
import type { FormInstance } from 'element-plus'
import VerificationGame from '../../components/VerificationGame.vue';
import { encode, decode } from 'js-base64';
import { ElMessage } from 'element-plus'

let state = reactive({
  showVerificationGame: false,
});

const startVerificationGame = () => {
  state.showVerificationGame = true;
}

const handleGameCompleted = () => {
  state.showVerificationGame = false;
}

let showVerificationGame = ref(false);

onMounted(() => {
  resetCode();
});

let captchaCanvas = ref(null);
let generatedCode = '';
const resetCode = () => {
  const canvas = captchaCanvas.value;
  if (!canvas) return;

  const ctx = canvas.getContext('2d');
  if (!ctx) return;

  // Generate a new four-digit code
  generatedCode = '';
  for (let i = 0; i < 4; i++) {
    generatedCode += Math.floor(Math.random() * 10);
  }

  // Clear the canvas
  ctx.clearRect(0, 0, canvas.width, canvas.height);

  // Draw background noise
  for (let i = 0; i < 500; i++) {  // Increase the number of noise points
    // Set the color to a random RGB color
    ctx.fillStyle = `rgb(${Math.random() * 256}, ${Math.random() * 256}, ${Math.random() * 256})`;

    // Draw a small rectangle at a random position with a random size between 1 and 3
    ctx.fillRect(Math.random() * canvas.width, Math.random() * canvas.height, Math.random() * 2 + 1, Math.random() * 2 + 1);
  }

  // Set a margin for the characters
  const margin = 30;  // adjust this value to change the spacing between characters

  // Calculate the width of each character area
  const charAreaWidth = (canvas.width - 2 * margin) / generatedCode.length;

  // Draw each character of the code
  for (let i = 0; i < generatedCode.length; i++) {
    const char = generatedCode[i];

    // Set the color to a random RGB color
    ctx.fillStyle = `rgb(${Math.random() * 256}, ${Math.random() * 256}, ${Math.random() * 256})`;

    // Set the font to a size between 20 and 40
    ctx.font = `${20 + Math.random() * 20}px Arial`;

    // Set the text align to center
    ctx.textAlign = 'center';
    ctx.textBaseline = 'middle';

    // Set a larger random scale and skew
    ctx.setTransform(1, Math.random() * 0.2 - 0.1, Math.random() * 0.2 - 0.1, 1, 0, 0);

    // Calculate the position of the character with a random offset
    const x = margin + i * charAreaWidth + charAreaWidth / 2 + (Math.random() - 0.5) * charAreaWidth * 0.3;
    const y = canvas.height / 2 + (Math.random() - 0.5) * canvas.height * 0.3;

    // Draw the text at a position based on the canvas width, the code length, and the margin
    ctx.fillText(char, x, y);

    // Reset the transform
    ctx.setTransform(1, 0, 0, 1, 0, 0);
  }
};

//from表单校验
const ruleFormRef = ref<FormInstance>()
// 这里存放数据
const user = reactive<loginReq>({
  account: '',
  password: '',
  verifyCode: ''
})
const users = reactive<loginReq>({
  account: '',
  password: '',
  verifyCode: ''
})
//校验
const validatePassword = (rule: any, value: any, callback: any) => {
  if (value === '') {
    callback(new Error('请输入密码'))
  } else {
    callback()
  }
}
const validateAccount = (rule: any, value: any, callback: any) => {
  if (value === '') {
    callback(new Error('请输入账号'))
  } else {
    callback()
  }
}
const validateVerification = (rule: any, value: any, callback: any) => {
  if (value === '') {
    callback(new Error('请输入验证码'))
  } else {
    callback()
  }
}
//校验
const rules = reactive({
  password: [{validator: validatePassword, trigger: 'blur'}],
  account: [{validator: validateAccount, trigger: 'blur'}],
  verifyCode: [{validator: validateVerification, trigger: 'blur'}],
})
const changeRegist = () => {
  router.replace('/register')
}
let imgUrl = ref("http://localhost:8080/api/user/verifyCode?time=" + new Date());
const resetImg = () => {
  imgUrl.value = "http://localhost:8080/api/user/verifyCode?time=" + new Date();
}

const onSubmit = (formEl: FormInstance | undefined) => {
  // console.log("lll:homePage")
  // router.replace('/homePage');

  if (!formEl) return;
  formEl.validate((valid) => {
    if (user.verifyCode !== generatedCode.toString()) {
      ElMessage.error('验证码错误！');
    } else {
      if (valid) {
        const requestData = {
          account: user.account,
          password: user.password,
        };

        login(requestData)
            .then((response) => {
              if (response.data.respCode === '000000') {
                ElMessage.success('登录成功');

                // 把信息存储到全局变量中
                tokenStore().setToken(response.data.token);
                console.log(response.data.userPri);
                accountStore().setAccount(user.account);
                priStore().setPri(response.data.userPri);
                loginStore().setLoginStatus(true);
                // 跳转到后台页面
                router.push('/layout');
              } else {
                ElMessage.error('账号或验证码错误！');
              }

            })

            .catch((error) => {
              //console.error(error);
              ElMessage.error('服务器未启动！');
            });


      } else {
        ElMessage.error('错误的提交！');
      }
    }

  });
};
const options = {
  fpsLimit: 60,
  interactivity: {
    detectsOn: 'canvas',
    events: {
      onClick: { // 开启鼠标点击的效果
        enable: true,
        mode: 'push'
      },
      onHover: { // 开启鼠标悬浮的效果(线条跟着鼠标移动)
        enable: true,
        mode: 'grab'
      },
      resize: true
    },
    modes: { // 配置动画效果
      bubble: {
        distance: 400,
        duration: 2,
        opacity: 0.8,
        size: 40
      },
      push: {
        quantity: 4
      },
      grab: {
        distance: 200,
        duration: 0.4
      },
      attract: { // 鼠标悬浮时，集中于一点，鼠标移开时释放产生涟漪效果
        distance: 200,
        duration: 0.4,
        factor: 5
      }
    }
  },
  particles: {
    color: {
      value: '#a1eafb' // 粒子点的颜色
    },
    links: {
      color: '#e0dcdc', // 线条颜色
      distance: 150,//线条距离
      enable: true,
      opacity: 0.4, // 不透明度
      width: 1.2 // 线条宽度
    },
    collisions: {
      enable: true
    },
    move: {
      attract: {enable: false, rotateX: 600, rotateY: 1200},
      bounce: false,
      direction: 'none',
      enable: true,
      out_mode: 'out',
      random: false,
      speed: 0.5, // 移动速度
      straight: false
    },
    number: {
      density: {
        enable: true,
        value_area: 800
      },
      value: 50//粒子数
    },
    opacity: {//粒子透明度
      value: 0.7
    },
    shape: {//粒子样式
      type: 'star'
    },
    size: {//粒子大小
      random: true,
      value: 10
    }
  },
  detectRetina: true
}
</script>
<style scoped>
.footer {
  position: fixed;
  bottom: 0;
  left: 0;
  width: 100%;
  padding: 10px;
  background-color: #18affa;
  text-align: center;
  font-size: 12px;
  color: #999;
}

.login {
  height: 100%;
  width: 100%;
  overflow: hidden;
}

.login__particles {
  height: 100%;
  width: 100%;
  background-size: cover;
  background-repeat: no-repeat;
  background-image: url('@/assets/1003.jpg');
  opacity: 0.9;
  position: fixed;
  pointer-events: none;
}

.loginPart {
  position: absolute;
  /*定位方式绝对定位absolute*/
  top: 50%;
  left: 75%;
  /*顶和高同时设置50%实现的是同时水平垂直居中效果*/
  transform: translate(-50%, -50%);
  /*实现块元素百分比下居中*/
  width: 500px;
  padding: 75px;
  background: rgba(255, 255, 255, 0.7);
  /*背景颜色为黑色，透明度为0.8*/
  box-sizing: border-box;
  /*box-sizing设置盒子模型的解析模式为怪异盒模型，
  将border和padding划归到width范围内*/
  box-shadow: 0px 15px 25px rgba(0, 0, 0, .5);
  /*边框阴影  水平阴影0 垂直阴影15px 模糊25px 颜色黑色透明度0.5*/
  border-radius: 15px;
  /*边框圆角，四个角均为15px*/
}

h2 {
  margin: 0 0 30px;
  padding: 0;
  color: #030303;
  text-align: center;
  /*文字居中*/

  font-size: 2.5rem;
  text-transform: uppercase;
  letter-spacing: 0.2rem;
  text-shadow: 0 0.2rem 0.4rem rgba(0, 0, 0, 0.3);
}

.btn {
  transform: translate(80px);
  width: 250px;
  height: 40px;
  font-size: 15px;
}

</style>
